package drds.common.db.xml_mapping.builder.xml;

import drds.common.db.xml_mapping.builder.BaseBuilder;
import drds.common.db.xml_mapping.builder.MapperBuilderAssistant;
import drds.common.db.xml_mapping.executor.key_generator.AutoSetModePrimaryKeyGenerator;
import drds.common.db.xml_mapping.executor.key_generator.NoPrimaryKeyGenerator;
import drds.common.db.xml_mapping.executor.key_generator.PrimaryKeyGenerator;
import drds.common.db.xml_mapping.mapping.SqlSource;
import drds.common.db.xml_mapping.mapping.SqlType;
import drds.common.db.xml_mapping.mapping.StatementType;
import drds.common.db.xml_mapping.parsing.XmlNode;
import drds.common.db.xml_mapping.script.LanguageDriver;
import drds.common.db.xml_mapping.session.Configuration;

import java.util.Locale;


public class XmlStatementBuilder extends BaseBuilder {

  private final MapperBuilderAssistant builderAssistant;
  private final XmlNode xmlNode;


  public XmlStatementBuilder(Configuration configuration, MapperBuilderAssistant builderAssistant, XmlNode xmlNode) {
    super(configuration);
    this.builderAssistant = builderAssistant;
    this.xmlNode = xmlNode;

  }

  public void parseStatementNode() {
    SqlType sqlType = SqlType.valueOf(xmlNode.getNode().getNodeName().toUpperCase(Locale.ENGLISH));
    String id = xmlNode.getStringAttribute("id");
    //进行include
    XmlIncludeTransformer xmlIncludeTransformer = new XmlIncludeTransformer(configuration, builderAssistant);
    xmlIncludeTransformer.applyIncludes(xmlNode.getNode());

    String parameterType = xmlNode.getStringAttribute("parameterType");
    Class<?> parameterTypeClass = resolveClass(parameterType);
    //

    String lang = xmlNode.getStringAttribute("lang");
    LanguageDriver languageDriver = getLanguageDriver(lang);
    SqlSource sqlSource = languageDriver.createSqlSource(configuration, xmlNode, parameterTypeClass);
    StatementType statementType = StatementType.valueOf(xmlNode.getStringAttribute("statementType", StatementType.prepared_statement.toString()));

    String parameterMap = xmlNode.getStringAttribute("parameterMap");
    String resultType = xmlNode.getStringAttribute("resultType");
    Class<?> resultTypeClass = resolveClass(resultType);
    String resultMap = xmlNode.getStringAttribute("resultMap");

    PrimaryKeyGenerator primaryKeyGenerator;
    {
      primaryKeyGenerator = xmlNode.getBooleanAttribute("useGeneratedKeys", configuration.isUseGeneratedKeys() && SqlType.insert.equals(sqlType))
        ? AutoSetModePrimaryKeyGenerator.INSTANCE : NoPrimaryKeyGenerator.INSTANCE;
    }
    //
    String keyProperty = xmlNode.getStringAttribute("keyProperty");
    String keyColumn = xmlNode.getStringAttribute("keyColumn");
    //
    String resultSets = xmlNode.getStringAttribute("resultSets");

    builderAssistant.addMappedStatement(
      id,
      sqlSource,
      statementType,
      sqlType,
      parameterMap,
      parameterTypeClass,
      resultMap,
      resultTypeClass,


      primaryKeyGenerator,
      keyProperty,
      keyColumn,
      //
      languageDriver,
      resultSets);
  }


  private LanguageDriver getLanguageDriver(String lang) {
    Class<? extends LanguageDriver> langClass = null;
    if (lang != null) {
      langClass = resolveClass(lang);
    }
    return configuration.getLanguageDriver(langClass);
  }

}
